 <?php
 class Packer{
 
  private $fileDescriptorCount;
  private $fileDescriptorLimit;
  private $zipArchive;
  private $archiveName;
  
  public function __construct(){
    $this->fileDescriptorCount = 0;
    $this->fileDescriptorLimit = 200;
    $this->zipArchive = NULL;
    $this->archiveName = '';
  }
  
  private function openArchive($archiveName){
      if($this->zipArchive = new ZipArchive()) {
        if($this->zipArchive->open($archiveName, ZIPARCHIVE::OVERWRITE) === true){
          $this->fileDescriptorCount = 0;
          $this->archiveName = $archiveName;
        } 
        else{
          print_r('Nie można otworzyć archiwum');
          exit;
        }         
      }      
      else{
        print_r('Nie można utworzyć archiwum');
        exit;
      }
  }


  private function reopenArchive(){
      $this->zipArchive->close();
      if($this->zipArchive = new ZipArchive()) {
        $this->zipArchive->open($this->archiveName);
        $this->fileDescriptorCount = 0;
      }      
      else{
        print_r('Nie można odtworzyć archiwum');
        exit;
      }
  }
  
  private function addFolderToZip($dir, $zipdir = ''){
      if (is_dir($dir)) {
          if ($dh = opendir($dir)) {

              //Add the directory
              if ($dir!='.' && $dir!='./')
                $this->zipArchive->addEmptyDir($dir);
              
              if (substr($dir,-1) !='/')
                $dir = $dir.'/';
              // Loop through all the files
              while (($file = readdir($dh)) !== false) {
            
              
                  //If it's a folder, run the function again!
                  if(!is_file($dir . $file)){
                      // Skip parent and root directories
                      if( ($file !== ".") && ($file !== "..")){
                          $this->addFolderToZip($dir . $file . "/", $zipdir . $file . "/");
                      }
                    
                  }else{
                      // Add the files
                      $this->zipArchive->addFile($dir . $file, $zipdir . $file);
                      $this->fileDescriptorCount++;
                      if ($this->fileDescriptorCount > $this->fileDescriptorLimit )
                        $this->reopenArchive();
                  }
              }
          }
      }
  } 
  
  private function extractZip( $zipFile = '', $zipDirectory="." ){
     define(DIRECTORY_SEPARATOR, '/');
      $zipDir = getcwd() . DIRECTORY_SEPARATOR . $zipDirectory. DIRECTORY_SEPARATOR;
      $zip = zip_open($zipDir.$zipFile);
      if ($zip){
          while ($zip_entry = zip_read($zip)){
              $completePath = $zipDir . dirname(zip_entry_name($zip_entry));
              $completeName = $zipDir . zip_entry_name($zip_entry);
              if(!file_exists($completePath)){
                  $tmp = '';
                  foreach(explode('/',$completePath) AS $k){
                      $tmp .= $k.'/';
                      if(!file_exists($tmp) ){
                          mkdir($tmp, 0777);
                      }
                  }
              }
              if (zip_entry_open($zip, $zip_entry, "r")){
                  if ($fd = @fopen($completeName, 'w+')){
                      fwrite($fd, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)));
                      fclose($fd);
                  }
                  else{
                      @mkdir($completeName, 0777);
                  }
                  zip_entry_close($zip_entry);
              }
          }
          zip_close($zip);
      }
      return true;
  }     
  
  public function extractArchive($archiveFilename = 'serwis.zip', $directory=".")
  {
    //extractZip używa starego interfejsu (proceduralnego)
    $this->extractZip($archiveFilename, $directory);
  } 
 
  public function createArchive($archiveFilename='serwis.zip', $directory=".")
  {
    $this->openArchive($archiveFilename);
    $this->addFolderToZip($directory);
  }
}  
//---------------------------------------------------------------------------------
  if ( isset($_GET['zip']) && $_GET['zip']==1){
    $packer = new Packer();
    $packer->createArchive();
  }
  else if (isset($_GET['unzip']) && $_GET['unzip']==1){
    $packer = new Packer();
    $packer->extractArchive();
  }
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl" lang="pl">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>zip utility</title>
</head>
<body>
  <div>
  <?php 
    if (isset($_GET['zip']) && $_GET['zip']==1){
      print '<h1>Serwis został spakowany</h1>';
    }
    else if (isset($_GET['unzip']) && $_GET['unzip']==1){
      print '<h1>Serwis został rozpakowany</h1>';
    }
    else{
      print '<a href="pack.php?zip=1">Spakuj serwis</a>';
      print '<a href="pack.php?unzip=1">Rozpakuj serwis</a>';
    } 
  ?>  
  </div>
</body>
</html>